package com.emm.yixun.website.listeners;

import com.emm.yixun.common.enums.ResponseEnums;
import com.emm.yixun.common.model.HaveReceiveRefund;
import com.emm.yixun.common.model.PayDeposit;
import com.emm.yixun.common.model.Project;
import com.emm.yixun.common.model.Subscribe;
import com.emm.yixun.common.model.dto.*;
import com.emm.yixun.common.model.enums.*;
import com.emm.yixun.common.response.Response;
import com.emm.yixun.common.response.ResponseList;
import com.emm.yixun.customer.service.CustomerServiceFacade;
import com.emm.yixun.customer.service.PayDepositServiceFacade;
import com.emm.yixun.customer.service.SubscribeServiceFacade;
import com.emm.yixun.customer.service.SubscribeTransServiceFacade;
import com.emm.yixun.customer.service.channel.ChannelSendHttpMessageService;
import com.emm.yixun.estate.service.ProjectRoomServiceFacade;
import com.emm.yixun.estate.service.ProjectServiceFacade;
import com.emm.yixun.marketing.service.HaveReceiveRefundServiceFacade;
import com.emm.yixun.marketing.service.NeedReceiveRefundServiceFacade;
import com.emm.yixun.marketing.service.RoomChangeHistoryServiceFacade;
import com.emm.yixun.system.service.notice.subscribe.SubscribeNoticeFacade;
import com.emm.yixun.website.common.utils.SpringWebContextUtil;
import com.emm.yixun.website.service.ActivitiProcessServiceImpl;
import com.emm.yixun.website.service.system.log.ActCommitLogService;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;

public class SubscribeListeners implements Serializable, ExecutionListener{
	private static final long serialVersionUID = -4663488123522935330L;
	private final Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Override
	public void notify(DelegateExecution execution) throws Exception {
		String id=execution.getProcessBusinessKey();
		String processInstanceId=execution.getProcessInstanceId();
		SubscribeServiceFacade subscribeServiceFacade=getSubscribeServiceFacade();
		//ProjectRoomServiceFacade projectRoomServiceFacade=getProjectRoomServiceFacade();
		PayDepositServiceFacade payDepositServiceFacade=getPayDepositServiceFacade();
		Response<Subscribe> subscribeResponse=subscribeServiceFacade.findById(Long.valueOf(id));
		if(!subscribeResponse.isSuccess()){
			throw new Exception("认购记录不存在");
		}
		Subscribe subscribe=subscribeResponse.getEntity();
		if(null==subscribe){
			throw new Exception("认购记录不存在");
		}
		if(getActivitiProcessServiceImpl().isCheckPass(processInstanceId)){
			
			boolean flag = checkAuditCommit(subscribe);
			if(!flag) {
				throw new Exception(ResponseEnums.RESPONSEENUMS_999999.getName());
			}
			
			/**
			 * 1.修改认购记录审核状态为通过   
			 * 2.记录房源变更记录
			 * 3.记录应收记录
			 * 4.更改客户交易状态为认筹，判断是否多套交易并更新状态
			 */
			//1.修改认筹记录审核状态为通过   
			SubscribeDto updateDto = new SubscribeDto();
			updateDto.setId(Long.valueOf(id));
			updateDto.setAuditStatus(AuditStatusEnum.SUCCESS.getNo());
			updateDto.setCheckDate(new Date());
			subscribeServiceFacade.updateByPrimaryKey(updateDto, true);
			if(subscribe.getPayDepositId()!=null){
				PayDepositDto payDepositDto = new PayDepositDto();
				payDepositDto.setBusinessStatus("2");
				payDepositDto.setId(subscribe.getPayDepositId());
				payDepositServiceFacade.updateByPrimaryKey(payDepositDto, true);
			}
			
			//2.记录房源变更记录
			RoomChangeHistoryDto dto=new RoomChangeHistoryDto();
			dto.setRoomId(subscribe.getRoomId());
			dto.setBusinessDynamics("认购");
			if(StringUtils.isBlank(subscribe.getPayDepositCode())){
				dto.setRemark("房源由【可售】转为【认购】");
			}else{
				dto.setRemark("房源由【小定】转为【认购】");
			}
			dto.setBusinessHref("/customer/subscribe/toView?id="+subscribe.getId()+"&returnUrl=,marketing,room,index");
    		dto.setMerchantId(subscribe.getMerchantId());
    		dto.setAccessCode(subscribe.getAccessCode());
    		dto.setCreateUserId(subscribe.getCreateUserId());
    		dto.setUserCode(subscribe.getUserCode());
    		dto.setDelFlag("0");
    		dto.setUpdateUserId(subscribe.getUpdateUserId());
    		dto.setUpdateTime(new Date());
    		Response<RoomChangeHistoryDto> rchSaveResponse=getRoomChangeHistoryServiceFacade().save(dto);
    		if(!rchSaveResponse.isSuccess()){
    			throw new Exception(rchSaveResponse.getResultMessage());
    		}
			
			//3.记录应收记录
			NeedReceiveRefundDto needReceiveRefundDto=new NeedReceiveRefundDto();
			needReceiveRefundDto.setRelationId(subscribe.getId());
			needReceiveRefundDto.setBusinessType("1");
			needReceiveRefundDto.setTotalReceivablesAmount(subscribe.getDepositReceivable());
			needReceiveRefundDto.setCustomerId(subscribe.getCustomerId());
			needReceiveRefundDto.setRoomId(subscribe.getRoomId());
			needReceiveRefundDto.setStatus("1");
			needReceiveRefundDto.setPostponedStatus("0");
			needReceiveRefundDto.setDocType("0");
			needReceiveRefundDto.setRemark("认购收款");
			needReceiveRefundDto.setHousingFundType(HousingFundTypeEnum.FUNDTYPE_3.getNo());//认购金
			needReceiveRefundDto.setBusinessFlag(BusinessFlagEnum.BUSINESSFLAG_5.getNo());
			needReceiveRefundDto.setPostponedStatus("0");
			
			needReceiveRefundDto.setMerchantId(subscribe.getMerchantId());
			needReceiveRefundDto.setUserCode(subscribe.getUserCode());
			needReceiveRefundDto.setAccessCode(subscribe.getAccessCode());
			needReceiveRefundDto.setCreateUserId(subscribe.getCreateUserId());
			needReceiveRefundDto.setDelFlag("0");
			needReceiveRefundDto.setUpdateUserId(subscribe.getUpdateUserId());
			needReceiveRefundDto.setUpdateTime(new Date());
			Response<NeedReceiveRefundDto> nrrdSaveResponse=getNeedReceiveRefundServiceFacade().save(needReceiveRefundDto);
			
			//验证是否开通绑定功能 2017-08-12
			Project project = getProjectServiceFacade().findById(subscribe.getProjectId()).getEntity();
			if(!StringUtils.isEmpty(project.getBindReceivables())&&"0".equals(project.getBindReceivables())){
			    if(subscribe.getDepositReceivable()==null||subscribe.getDepositReceivable().compareTo(BigDecimal.ZERO)==0){
				SubscribeTransRequestDto subscribeTransRequestDto = new SubscribeTransRequestDto();
				subscribeTransRequestDto.setSubId(subscribe.getId());
				subscribeTransRequestDto.setTransAmount(subscribe.getSubscribeAmount());
				getSubscribeTransServiceFacade().subcribeTrans(subscribeTransRequestDto);
			    }
			}
			if(!nrrdSaveResponse.isSuccess()){
    			throw new Exception(nrrdSaveResponse.getResultMessage());
    		}
			
			//认筹金转认购金
			if(subscribe.getPayDepositId()!=null){
				HaveReceiveRefundDto entity = new HaveReceiveRefundDto();
				entity.setRelationId(subscribe.getPayDepositId());
				entity.setBusinessFlag(BusinessFlagEnum.BUSINESSFLAG_1.getNo());
				entity.setDelFlag("0");
				entity.setDocType("0");
				ResponseList<HaveReceiveRefund> resList = getHaveReceiveRefundServiceFacade().findByDto(entity);
				BigDecimal realAmount = new BigDecimal("0");
				if(resList.getEntity() != null){
					for(int i = 0; i < resList.getEntity().size(); i++){
						HaveReceiveRefund have = (HaveReceiveRefund)resList.getEntity().get(i);
						realAmount = realAmount.add(have.getRealAmount());
						HaveReceiveRefundDto haveDto = new HaveReceiveRefundDto();
						haveDto.setId(have.getId());
						haveDto.setBusinessFlag(BusinessFlagEnum.BUSINESSFLAG_2.getNo()); 
						haveDto.setTransferStatus("1"); //已转出
						Response<Integer> resUpdate = getHaveReceiveRefundServiceFacade().updateByPrimaryKey(haveDto, true);
						if(!resUpdate.isSuccess()){
			    			throw new Exception(resUpdate.getResultMessage());
			    		}
					}
					HaveReceiveRefundDto haveReceiveRefundDto = new HaveReceiveRefundDto();
					haveReceiveRefundDto.setReceivablesId(nrrdSaveResponse.getEntity().getId());
					haveReceiveRefundDto.setReceivablesType(BusinessTypeEnum.SUBSCRIBE.getNo());
					haveReceiveRefundDto.setRelationId(subscribe.getId());
					haveReceiveRefundDto.setRealAmount(realAmount);
					haveReceiveRefundDto.setDeductibleAmount(new BigDecimal("0"));
					haveReceiveRefundDto.setCustomerId(subscribe.getCustomerId());
					haveReceiveRefundDto.setRoomId(subscribe.getRoomId());
					haveReceiveRefundDto.setRemark("认筹金转认购金(转入)");
					haveReceiveRefundDto.setHousingFundType(HousingFundTypeEnum.FUNDTYPE_3.getNo());//认购金
					haveReceiveRefundDto.setBusinessFlag(BusinessFlagEnum.BUSINESSFLAG_7.getNo()); //认筹金转认购金(转入)
					haveReceiveRefundDto.setMerchantId(subscribe.getMerchantId());
					haveReceiveRefundDto.setUserCode(subscribe.getUserCode());
					haveReceiveRefundDto.setAccessCode(subscribe.getAccessCode());
					haveReceiveRefundDto.setCreateUserId(subscribe.getCreateUserId());
					haveReceiveRefundDto.setDelFlag("0");
					haveReceiveRefundDto.setDocType("0");
					haveReceiveRefundDto.setTransferStatus("0");
					haveReceiveRefundDto.setReChecked("0");
					haveReceiveRefundDto.setStatementType(Long.parseLong(StatementTypeEnum.TRANSFER.getNo()));
					haveReceiveRefundDto.setStatementDate(new Date());
					Response<HaveReceiveRefundDto> resHave = getHaveReceiveRefundServiceFacade().save(haveReceiveRefundDto);
					if(!resHave.isSuccess()){
		    			throw new Exception(resHave.getResultMessage());
		    		}
				}
			}
			
			
			//4.更改客户交易状态为认筹，判断是否多套交易并更新状态 todo
			/**
			 * 4.更改客户交易状态为认购，判断是否多套交易并更新状态 todo
			 * @param bugType 业务类型： 1 认筹、2 认购、3 签约
			 * @param busId 对应业务类型Id
			 * @param customerId 客户Id
			 * @param userId 用户Id
			 */
			payDepositServiceFacade.getCustomerEntity("2", Long.valueOf(id),subscribe.getCustomerId() , subscribe.getUpdateUserId());

			CustomerServiceFacade customerServiceFacade = getCustomerServiceFacade();
			customerServiceFacade.changeCustomerLevel(subscribe.getCustomerId(), null);
			try {
				/**
				 * （认购审核通过）推送消息到app
				 * @author ny
				 * @param param noticeType 提醒类型, noticeBusinessId 业务主键Id
				 * @return 【${auditStatus}】房号：${roomName}；客户：${customer};
				 */
				NoticeEntity noticeEntity = new NoticeEntity();
				noticeEntity.setNoticeBusinessId(subscribe.getId());
				noticeEntity.setNoticeType("3");
				noticeEntity.setProcessInstanceId(processInstanceId);
				getSubscribeNoticeFacade().createSubscribeNotice(noticeEntity);
			
				/**
				 * 推送到渠道
				 */
				getChannelSendHttpMessageService().sendTransaction(subscribe.getId(), TransTypeEnum.SUBSCRIBE.getNo(), false);
			} catch (Exception e) {
				logger.error("认购审批推送数据失败", e);
			}

		}else{
			
			boolean flag = checkAuditCommit(subscribe);
			if(!flag) {
				throw new Exception(ResponseEnums.RESPONSEENUMS_999999.getName());
			}
			
			/**
			 * 1.修改认筹记录审核状态为不通过
			 * 2.修改房源状态为未售或者认筹
			 */

			SubscribeDto updateDto = new SubscribeDto();
			updateDto.setId(subscribe.getId());
			updateDto.setAuditStatus(AuditStatusEnum.REJECT.getNo());
			updateDto.setCheckDate(new Date());
			subscribeServiceFacade.updateByPrimaryKey(updateDto, true);

			//判断是否还有审核中或者审核通过的数据，以此来判断是否返回到可售
			PayDepositDto payDepositDto = new PayDepositDto();
			payDepositDto.setM_auditStatus(" and t.audit_status in (1,3)");
			payDepositDto.setRoomId(subscribe.getRoomId());
			ResponseList<PayDeposit> responseList = payDepositServiceFacade.findByDtoJ(payDepositDto);
			//房源状态为未售或者认筹
			if(responseList.getEntity()==null||responseList.getEntity().size()==0){
				ProjectRoomDto projectRoomDto = new ProjectRoomDto();
				projectRoomDto.setId(subscribe.getRoomId());
				projectRoomDto.setRoomStatus(RoomStatusEnum.VENDIBILITY.getNo());//可售
				Response<Integer> responseRoomDto=getProjectRoomServiceFacade().updateByPrimaryKey(projectRoomDto, true);
				if(!responseRoomDto.isSuccess()){
					throw new Exception("房间状态为可售出错");
				}
			}else{
				ProjectRoomDto projectRoomDto = new ProjectRoomDto();
				projectRoomDto.setId(subscribe.getRoomId());
				projectRoomDto.setRoomStatus(RoomStatusEnum.RESERVE.getNo());//认筹
				Response<Integer> responseRoomDto=getProjectRoomServiceFacade().updateByPrimaryKey(projectRoomDto, true);
				if(!responseRoomDto.isSuccess()){
					throw new Exception("房间状态为认筹出错");
				}
			}
			//房源状态为未售或者认筹
//			ProjectRoomDto projectRoomDto=new ProjectRoomDto();
//			projectRoomDto.setId(subscribe.getRoomId());
//			projectRoomDto.setRoomStatus(RoomStatusEnum.VENDIBILITY.getNo());
//			projectRoomServiceFacade.updateByPrimaryKey(projectRoomDto, true);
			
			/**
			 * （认购审核不通过）推送消息到app
			 * @author ny
			 * @param param noticeType 提醒类型, noticeBusinessId 业务主键Id
			 * @return 【${auditStatus}】房号：${roomName}；客户：${customer};
			 */
			NoticeEntity noticeEntity = new NoticeEntity();
			noticeEntity.setNoticeBusinessId(subscribe.getId());
			noticeEntity.setNoticeType("3");
			noticeEntity.setProcessInstanceId(processInstanceId);
			getSubscribeNoticeFacade().createSubscribeNotice(noticeEntity);
		}
	}
	
	/**
	 * 前置判断,审核记录是否已经提交,防止重复提交
	 * 产生原因: 提交审核,后台处理中时,刷新页面再次提交审核,会重复
	 * true: 可继续执行
	 * false: 不可执行
	 */
	public boolean checkAuditCommit(Subscribe entity) {
		
		// 业务数据为null时,默认通过.为了不改变老业务,不影响流程正常行走
		if (null == entity) {
			return true;
		}
		return getActcommitLogService().checkActCommit(entity.getAuditStatus(), entity.getMerchantId(), entity.getId(),
				entity.getProcInstId(), "认购", "PC");
	}
	
	private SubscribeNoticeFacade getSubscribeNoticeFacade(){
		return (SubscribeNoticeFacade)SpringWebContextUtil.getApplicationContext().getBean("subscribeNoticeFacade");
	}
	
	private ProjectRoomServiceFacade getProjectRoomServiceFacade(){
		return (ProjectRoomServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("projectRoomServiceFacade");
	}
	private PayDepositServiceFacade getPayDepositServiceFacade(){
		return (PayDepositServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("payDepositServiceFacade");
	}
	private SubscribeServiceFacade getSubscribeServiceFacade(){
		return (SubscribeServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("subscribeServiceFacade");
	}
	
	private ActivitiProcessServiceImpl getActivitiProcessServiceImpl(){
		return (ActivitiProcessServiceImpl)SpringWebContextUtil.getApplicationContext().getBean("activitiProcessServiceImpl");
	}
	
	private RoomChangeHistoryServiceFacade getRoomChangeHistoryServiceFacade(){
		return (RoomChangeHistoryServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("roomChangeHistoryServiceFacade");
	}
	
	private NeedReceiveRefundServiceFacade getNeedReceiveRefundServiceFacade(){
		return (NeedReceiveRefundServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("needReceiveRefundServiceFacade");
	}

	private HaveReceiveRefundServiceFacade getHaveReceiveRefundServiceFacade(){
		return (HaveReceiveRefundServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("haveReceiveRefundServiceFacade");
	}

	private ChannelSendHttpMessageService getChannelSendHttpMessageService(){
	    return (ChannelSendHttpMessageService)SpringWebContextUtil.getApplicationContext().getBean("channelSendHttpMessageService");
	}
	
	private ProjectServiceFacade getProjectServiceFacade(){
	    return (ProjectServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("projectServiceFacade");
	}
	
	private SubscribeTransServiceFacade getSubscribeTransServiceFacade(){
	    return (SubscribeTransServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("subscribeTransServiceFacade");
	}
	
	private ActCommitLogService getActcommitLogService(){
		return (ActCommitLogService)SpringWebContextUtil.getApplicationContext().getBean("actCommitLogService");
	}

	private CustomerServiceFacade getCustomerServiceFacade(){
		return (CustomerServiceFacade)SpringWebContextUtil.getApplicationContext().getBean("customerServiceFacade");
	}

}
